(* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is TurboPower Abbrevia
 *
 * The Initial Developer of the Original Code is
 * TurboPower Software
 *
 * Portions created by the Initial Developer are Copyright (C) 1997-2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** *)

 {*********************************************************}
 {* ABBREVIA: AbZipper.pas 3.05                           *}
 {*********************************************************}
 {* ABBREVIA: Non-visual Component with Zip support       *}
 {*********************************************************}

unit AbZipper;

{$I AbDefine.inc}

interface

uses
  SysUtils, Classes,
  AbBrowse, AbZBrows,
  AbBase, AbUtils, AbArcTyp, AbZipTyp, AbTarTyp, AbGzTyp, AbSpanSt;

type
  TAbCustomZipper = class(TAbCustomZipBrowser)
  protected {private}
    FAutoSave: boolean;
    FCompressionMethodToUse: TAbZipSupportedMethod;
    FDeflationOption: TAbZipDeflationOption;
    FDOSMode: boolean;
    FOnConfirmSave: TAbArchiveConfirmEvent;
    FOnSave: TAbArchiveEvent;
    FOnArchiveSaveProgress: TAbArchiveProgressEvent;                 {!!.04}
    FArchiveSaveProgressMeter: TAbMeterLink;                          {!!.04}

    FStoreOptions: TAbStoreOptions;

  protected {methods}
    procedure DoConfirmSave(Sender: TObject; var Confirm: boolean);
      virtual;
    procedure DoSave(Sender: TObject);
      virtual;
    procedure DoArchiveSaveProgress(Sender: TObject; Progress: byte;{!!.04}
      var Abort: boolean);             {!!.04}

    procedure InitArchive;
      override;
    procedure SetAutoSave(Value: boolean);
    procedure SetCompressionMethodToUse(Value: TAbZipSupportedMethod);
    procedure SetDeflationOption(Value: TAbZipDeflationOption);
    procedure SetDOSMode(Value: boolean);
    procedure SetFileName(const aFileName: string);
      override;
    procedure SetStoreOptions(Value: TAbStoreOptions);
    procedure SetZipfileComment(const Value: string);
      override;
    procedure ZipProc(Sender: TObject; Item: TAbArchiveItem;
      OutStream: TStream);
    procedure ZipFromStreamProc(Sender: TObject; Item: TAbArchiveItem;
      OutStream, InStream: TStream);
    procedure Notification(Component: TComponent;                      {!!.04}
      Operation: TOperation); override;                                {!!.04}
    procedure ResetMeters; override;                                   {!!.04}

  protected {properties}
    property AutoSave: boolean Read FAutoSave Write SetAutoSave;
    property CompressionMethodToUse: TAbZipSupportedMethod
      Read FCompressionMethodToUse Write SetCompressionMethodToUse default
      AbDefCompressionMethodToUse;
    property DeflationOption: TAbZipDeflationOption
      Read FDeflationOption Write SetDeflationOption default AbDefDeflationOption;
    property DOSMode: boolean Read FDOSMode Write SetDOSMode;
    property StoreOptions: TAbStoreOptions Read FStoreOptions
      Write SetStoreOptions default AbDefStoreOptions;
    property ArchiveSaveProgressMeter: TAbMeterLink                   {!!.04}
      Read FArchiveSaveProgressMeter                                  {!!.04}
      Write FArchiveSaveProgressMeter;                                 {!!.04}


  protected {events}
    property OnConfirmSave: TAbArchiveConfirmEvent
      Read FOnConfirmSave Write FOnConfirmSave;
    property OnSave: TAbArchiveEvent Read FOnSave Write FOnSave;
    property OnArchiveSaveProgress: TAbArchiveProgressEvent           {!!.04}
      Read FOnArchiveSaveProgress                                      {!!.04}
      Write FOnArchiveSaveProgress;                                    {!!.04}

  public {methods}
    constructor Create(AOwner: TComponent);
      override;
    destructor Destroy;
      override;
    procedure AddFiles(const FileMask: string; SearchAttr: integer);
    procedure AddFilesEx(const FileMask, ExclusionMask: string; SearchAttr: integer);
    procedure AddFromStream(const NewName: string; FromStream: TStream);
    procedure DeleteAt(Index: integer);
    procedure DeleteFiles(const FileMask: string);
    procedure DeleteFilesEx(const FileMask, ExclusionMask: string);
    procedure DeleteTaggedItems;
    procedure FreshenFiles(const FileMask: string);
    procedure FreshenFilesEx(const FileMask, ExclusionMask: string);
    procedure FreshenTaggedItems;
    procedure Move(aItem: TAbArchiveItem; const NewStoredPath: string);
    procedure Save;
    procedure Replace(aItem: TAbArchiveItem);
  end;

type
  TAbZipper = class(TAbCustomZipper)
  published
    property ArchiveProgressMeter;
    property ArchiveSaveProgressMeter;                                 {!!.04}
    property ItemProgressMeter;
    property AutoSave;
    property BaseDirectory;
    property CompressionMethodToUse;
    property DeflationOption;
    property DOSMode;
    property SpanningThreshold;
    property LogFile;
    property Logging;
    property OnArchiveProgress;
    property OnArchiveSaveProgress;                                    {!!.04}
    property OnArchiveItemProgress;
    property OnChange;
    property OnConfirmProcessItem;
    property OnConfirmSave;
    property OnLoad;
    property OnProcessItemFailure;
    property OnRequestBlankDisk;
    property OnRequestImage;
    property OnRequestLastDisk;
    property OnRequestNthDisk;
    property OnSave;
    property Password;
    property StoreOptions;
    property TempDirectory;
    property Version;
    property FileName; {must be after OnLoad}
  end;

implementation

uses
  AbExcept,
  AbZipPrc;

{ -------------------------------------------------------------------------- }
constructor TAbCustomZipper.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  CompressionMethodToUse := AbDefCompressionMethodToUse;
  DeflationOption := AbDefDeflationOption;
  StoreOptions := AbDefStoreOptions;
end;

{ -------------------------------------------------------------------------- }
destructor TAbCustomZipper.Destroy;
begin
  inherited Destroy;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFiles(const FileMask: string; SearchAttr: integer);
{Add files to the archive where the disk filespec matches}
begin
  if (ZipArchive <> nil) then
    ZipArchive.AddFiles(FileMask, SearchAttr)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFilesEx(const FileMask, ExclusionMask: string;
  SearchAttr: integer);
{Add files that match Filemask except those matching ExclusionMask}
begin
  if (ZipArchive <> nil) then
    ZipArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFromStream(const NewName: string;
  FromStream: TStream);
{Add stream directly to archive}
begin
  if (ZipArchive <> nil) then
  begin
    FromStream.Position := 0;
    ZipArchive.AddFromStream(NewName, FromStream);
  end else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteFiles(const FileMask: string);
{delete all files from the archive that match the file mask}
begin
  if (ZipArchive <> nil) then
    ZipArchive.DeleteFiles(FileMask)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteAt(Index: integer);
{delete item at Index}
begin
  if (ZipArchive <> nil) then
    ZipArchive.DeleteAt(Index)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteFilesEx(const FileMask, ExclusionMask: string);
{Delete files that match Filemask except those matching ExclusionMask}
begin
  if (ZipArchive <> nil) then
    ZipArchive.DeleteFilesEx(FileMask, ExclusionMask)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteTaggedItems;
{delete all tagged items from the archive}
begin
  if (ZipArchive <> nil) then
    ZipArchive.DeleteTaggedItems
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DoConfirmSave(Sender: TObject; var Confirm: boolean);
begin
  Confirm := True;
  if Assigned(FOnConfirmSave) then
    FOnConfirmSave(Self, Confirm);
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DoSave(Sender: TObject);
begin
  if Assigned(FOnSave) then
    FOnSave(Self);
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenFiles(const FileMask: string);
{freshen all items that match the file mask}
begin
  if (ZipArchive <> nil) then
    ZipArchive.FreshenFiles(FileMask)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenFilesEx(const FileMask, ExclusionMask: string);
{freshen all items matching FileMask except those matching ExclusionMask}
begin
  if (ZipArchive <> nil) then
    ZipArchive.FreshenFilesEx(FileMask, ExclusionMask)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenTaggedItems;
{freshen all tagged items}
begin
  if (ZipArchive <> nil) then
    ZipArchive.FreshenTaggedItems
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.InitArchive;
begin
  inherited InitArchive;
  if (ZipArchive <> nil) then
  begin
    if (ZipArchive is TAbZipArchive) then
    begin
      {properties}
      ZipArchive.AutoSave := FAutoSave;
      TAbZipArchive(ZipArchive).CompressionMethodToUse := FCompressionMethodToUse;
      TAbZipArchive(ZipArchive).DeflationOption := FDeflationOption;
      FArchive.DOSMode  := FDOSMode;
      ZipArchive.StoreOptions := FStoreOptions;
      {events}
      ZipArchive.OnArchiveSaveProgress := DoArchiveSaveProgress; {!!.04}
      ZipArchive.OnConfirmSave := DoConfirmSave;
      TAbZipArchive(ZipArchive).OnRequestBlankDisk := OnRequestBlankDisk;
      ZipArchive.OnSave := DoSave;
      TAbZipArchive(ZipArchive).InsertHelper := ZipProc;
      TAbZipArchive(ZipArchive).InsertFromStreamHelper := ZipFromStreamProc;
    end;
  end;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Move(aItem: TAbArchiveItem; const NewStoredPath: string);
{renames the item}
begin
  if (ZipArchive <> nil) then
    ZipArchive.Move(aItem, NewStoredPath)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Replace(aItem: TAbArchiveItem);
{replace the item}
begin
  if (ZipArchive <> nil) then
    ZipArchive.Replace(aItem)
  else
    raise EAbNoArchive.Create;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Save;
begin
  if (ZipArchive <> nil) then
  begin
    ZipArchive.Save;
    DoChange;
  end;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetAutoSave(Value: boolean);
begin
  FAutoSave := Value;
  if (ZipArchive <> nil) then
    ZipArchive.AutoSave := Value;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetCompressionMethodToUse(Value: TAbZipSupportedMethod);
begin
  FCompressionMethodToUse := Value;
  if (ZipArchive <> nil) then
    (ZipArchive as TAbZipArchive).CompressionMethodToUse := Value;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetDeflationOption(Value: TAbZipDeflationOption);
begin
  FDeflationOption := Value;
  if (ZipArchive <> nil) then
    (ZipArchive as TAbZipArchive).DeflationOption := Value;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetDOSMode(Value: boolean);
begin
  FDOSMode := Value;
  if (ZipArchive <> nil) then
    ZipArchive.DOSMode := Value;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetFileName(const aFileName: string);
var
  ArcType: TAbArchiveType;
begin

  FFileName := aFileName;
  if (csDesigning in ComponentState) then
    Exit;
  {!!.05 Remove Try|Except Raise and double Free }
  if Assigned(FArchive) then
  begin
    FArchive.Save;
    FArchive.Free;
  end;
  FArchive := nil;

  ArcType := ArchiveType;

  if (FileName <> '') then
    if FileExists(FileName) then
    begin { open it }

      if not ForceType then
        ArcType := AbDetermineArcType(FileName, atUnknown);


      case ArcType of
        atZip, atSpannedZip, atSelfExtZip:
        begin                        {!!.02}
          FArchive := TAbZipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
          InitArchive;
        end;

        atTar:
        begin
          FArchive := TAbTarArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
          inherited InitArchive;
        end;

        atGZip:
        begin
          FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or
            fmShareDenyNone);
          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
          TAbGzipArchive(FArchive).IsGzippedTar := False;
          inherited InitArchive;
        end;

        atGZippedTar:
        begin
          FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or
            fmShareDenyNone);
          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
          TAbGzipArchive(FArchive).IsGzippedTar := True;
          inherited InitArchive;
        end;

        else
          raise EAbUnhandledType.Create;
      end {case};
      FArchive.Load;
      FArchiveType := ArcType;

    end else
    begin  { file doesn't exist, so create a new one }
      if not ForceType then                                              {!!.01}
        ArcType := AbDetermineArcType(FileName, atUnknown);              {!!.01}

      case ArcType of                                                    {!!.01}
        atZip:
        begin
          FArchive := TAbZipArchive.Create(FileName, fmCreate);
          InitArchive;
        end;

        atTar:
        begin
          FArchive := TAbTarArchive.Create(FileName, fmCreate or fmShareDenyNone);
          inherited InitArchive;
        end;

        atGZip:
        begin
          FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);
          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
          TAbGzipArchive(FArchive).IsGzippedTar := False;
          inherited InitArchive;
        end;

        atGZippedTar:
        begin
          FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);
          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
          TAbGzipArchive(FArchive).IsGzippedTar := True;
          inherited InitArchive;
        end;

        else
          raise EAbUnhandledType.Create;
      end {case};

      FArchiveType := ArcType;
    end;
  DoChange;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetStoreOptions(Value: TAbStoreOptions);
begin
  FStoreOptions := Value;
  if (ZipArchive <> nil) then
    ZipArchive.StoreOptions := Value;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetZipfileComment(const Value: string);
begin
  if (ZipArchive <> nil) then
    (ZipArchive as TAbZipArchive).ZipfileComment := Value
  else
    raise EAbNoArchive.Create;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ZipProc(Sender: TObject; Item: TAbArchiveItem;
  OutStream: TStream);
begin
  AbZip(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ZipFromStreamProc(Sender: TObject;
  Item: TAbArchiveItem; OutStream, InStream: TStream);
begin
  if Assigned(InStream) then
    AbZipFromStream(TAbZipArchive(Sender), TAbZipItem(Item),
      OutStream, InStream)
  else
    raise EAbZipNoInsertion.Create;
end;

 { -------------------------------------------------------------------------- }
 {!!.04 - Added}
procedure TAbCustomZipper.DoArchiveSaveProgress(Sender: TObject;
  Progress: byte;
  var Abort: boolean);
begin
  Abort := False;
  if Assigned(FArchiveSaveProgressMeter) then
    FArchiveSaveProgressMeter.DoProgress(Progress);
  if Assigned(FOnArchiveSaveProgress) then
    FOnArchiveSaveProgress(Self, Progress, Abort);
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Notification(Component: TComponent;
  Operation: TOperation);
begin
  inherited Notification(Component, Operation);
  if (Operation = opRemove) then
    if Component = FArchiveSaveProgressMeter then
      FArchiveSaveProgressMeter := nil;
end;

{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ResetMeters;
begin
  inherited ResetMeters;
  if Assigned(FArchiveSaveProgressMeter) then
    FArchiveSaveProgressMeter.Reset;
end;

 {!!.04 - Added end}
 { -------------------------------------------------------------------------- }


end.
